package org.tron.trident.component;

import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.tron.trident.common.Deposit;
import org.tron.trident.entity.Account;
import org.tron.trident.event.DepositEvent;
import org.tron.trident.service.AccountService;
import org.tron.trident.service.Trc20Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Data
public class Watcher{
    private Logger logger = LoggerFactory.getLogger(Watcher.class);
    @Autowired
    private AccountService accountService;
    @Autowired
    private Trc20Service trc20Service;
    @Value("${tron.contract-address}")
    private String contractAddress;//hex格式

    @Value("${tron.address}")
    private String address;//发币地址 hex格式

    @Value("${tron.private-key}")
    private String privateKey;//私钥
    private boolean stop = false;
    //默认同步间隔20秒
    private Long checkInterval = 2000L;
    private Long currentBlockHeight = 0L;
    private int step = 5;
    private DepositEvent depositEvent;

    public void check() {
        try {
            System.out.println(accountService+":::"+address);
            //获取所有的账户
            List<Account> accountList = accountService.findAll();
            if(!CollectionUtils.isEmpty(accountList)){
                List<Deposit> depositList = this.transferToOwner(accountList);
                if (!CollectionUtils.isEmpty(depositList)) {
                    depositList.forEach(deposit -> {
                        System.out.println(deposit);
                        depositEvent.onConfirmed(deposit);
                    });
                } else {
                    logger.info("{} 充值记录为空", new Date());
                }
            }else{
                logger.info("mogo中用户为空");
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<Deposit> transferToOwner(List<Account> accountList) {
        if (!CollectionUtils.isEmpty(accountList)) {
            List<Deposit> depositList = new ArrayList<>();
            accountList.stream().forEach(account -> {
                BigInteger contractBalance = trc20Service.balanceOf(account.getAddress());
                logger.info(account.getAddress()+"余额"+contractBalance);
                if (contractBalance.compareTo(new BigInteger("0")) > 0) {
                    String txId = trc20Service.transferContract(account.getAddress(), account.getPrivateKey(), Long.valueOf(contractBalance.toString()));
                    if (!StringUtils.isEmpty(txId)) {
                        Deposit deposit = new Deposit();
                        deposit.setTxid(txId);
                        deposit.setAddress(account.getAddress());
                        deposit.setAmount(new BigDecimal(contractBalance));
                        deposit.setTime(Calendar.getInstance().getTime());
                        depositList.add(deposit);
                    }

                }
            });
            return depositList;
        } else {
            return null;
        }

    }

    public void run() {
        stop = false;
        long nextCheck = 0;
        while (!(Thread.interrupted() || stop)) {
            if (nextCheck <= System.currentTimeMillis()) {
                try {
                    nextCheck = System.currentTimeMillis() + checkInterval;
                    logger.info("check...");
                    check();
                } catch (Exception ex) {
                    logger.info(ex.getMessage());
                }
            } else {
                try {
                    Thread.sleep(Math.max(nextCheck - System.currentTimeMillis(), 100));
                } catch (InterruptedException ex) {
                    logger.info(ex.getMessage());
                }
            }
        }
    }
}
